package org.snusmumr.android.media.data.adapter;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.snusmumr.android.media.LentItemsTab.OnCheckedListener;
import org.snusmumr.android.media.R;
import org.snusmumr.android.media.data.DatabaseProvider;
import org.snusmumr.android.media.data.DatabaseProvider.DatabaseMode;
import org.snusmumr.android.media.data.MediaColumns;
import org.snusmumr.android.media.util.Utils;

import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ExpandableListAdapter;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.SimpleCursorTreeAdapter.ViewBinder;
import android.widget.TextView;

public class LentItemsListAdapter implements ExpandableListAdapter {
	public enum LentItemsGroupBy {Friend, Author};
	
	private class AdapterImpl extends SimpleCursorTreeAdapter {

		public AdapterImpl(Context context, Cursor cursor, int groupLayout,
				String[] groupFrom, int[] groupTo, int childLayout,
				String[] childFrom, int[] childTo) {
			super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childFrom,
					childTo);
		}

		@Override
		protected Cursor getChildrenCursor(Cursor groupCursor) {
			int queryId;
			switch (groupBy) {
			case Friend:
				queryId = R.string.sql_fetch_lent_items_by_friend_id;
				break;

			case Author:
				queryId = R.string.sql_fetch_lent_items_by_author_id;
				break;
				
			default:
				queryId = R.string.sql_fetch_lent_items_by_friend_id;
				break;
			}
//			childrenCursor = dbProvider.getDatabase(DatabaseMode.Read)
//				.rawQuery(res.getString(queryId), new String[]{getParentItemId(groupCursor)});
//			
//			return childrenCursor;
			
			String parentItemId = getParentItemId(groupCursor);
			Cursor cursor = childrenCursors.get(parentItemId);
			if(cursor == null) {
				Log.d(TAG, "Create children cursor for parentId: " + parentItemId);
				cursor = dbProvider.getDatabase(DatabaseMode.Read)
						.rawQuery(res.getString(queryId), new String[]{parentItemId});
				childrenCursors.put(parentItemId, cursor);
			}
			
			return cursor;
			
		}
		
		@Override
		protected void bindChildView(View view, Context context, Cursor cursor,
				boolean isLastChild) {
			super.bindChildView(view, context, cursor, isLastChild);
			CheckBox checkBox = (CheckBox) view.findViewById(R.id.check_lent_list_item);
			int columnIndex = cursor.getColumnIndex(MediaColumns._ID);
			Long id = cursor.getLong(columnIndex );
			
			System.out.println("bind chind view: id=" + id);
			System.out.println("selectedIds: " + Utils.getAsString(selectedIds));
			System.out.println("set checked: " + checkBox.isChecked());
			System.out.println("must be checked: " + selectedIds.contains(id));
			
//			checkBox.setChecked(selectedIds.contains(id));
			checkBox.setOnCheckedChangeListener(new CheckListenerById(id, selectedIds) {
				@Override
				public void onChecked(boolean isChecked, Long id, int selectionCount) {
					itemCheckedListener.onChecked(selectionCount);
				}
				
			});
			
			checkBox.setChecked(selectedIds.contains(id));
		}
		
	}

	private static final String TAG = LentItemsListAdapter.class.getSimpleName();
	
	private AdapterImpl adapter;
	private DatabaseProvider dbProvider;
	private LentItemsGroupBy groupBy = LentItemsGroupBy.Friend;
	private HashMap<String, Cursor> childrenCursors;
	private Cursor groupCursor;
	private Resources res;
	private DateFormat dateFormat;
	private ArrayList<Long> selectedIds;
	private OnCheckedListener itemCheckedListener;
	
	public LentItemsListAdapter(Context context, Cursor cursor, int groupLayout,
			String[] groupFrom, int[] groupTo, int childLayout,
			String[] childFrom, int[] childTo, OnCheckedListener itemCheckedListener, LentItemsGroupBy groupBy) {
		initialize(context, cursor, itemCheckedListener, groupBy);
		this.adapter = new AdapterImpl(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childFrom, childTo);
		this.adapter.setViewBinder(new ViewBinder() {
			
			@Override
			public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
				if(view.getId() == R.id.tv_lent_date) {
					String lentToFull = "";
					try {
						Date lentDate = Utils.getDateFromDB(cursor.getString(columnIndex));
						if(lentDate != null)
							lentToFull = dateFormat.format(lentDate);
					} catch (ParseException e) {
						e.printStackTrace();
					}
					((TextView) view).setText(lentToFull);
					return true;
				}
				return false;
			}
		});
	}
	
	private void initialize(Context context, Cursor cursor, OnCheckedListener itemCheckedListener, LentItemsGroupBy groupBy) {
		Log.i(TAG, "init LentItemsListAdapter");
		this.dbProvider = DatabaseProvider.getInstance(context);
		this.res = context.getResources();
		this.groupBy = groupBy;
		this.groupCursor = cursor;
		this.childrenCursors = new HashMap<String, Cursor>(cursor.getCount());
		this.dateFormat = android.text.format.DateFormat.getMediumDateFormat(context.getApplicationContext());
		this.selectedIds = new ArrayList<Long>();
		this.itemCheckedListener = itemCheckedListener;
		Log.i(TAG, "init LentItemsListAdapter successful");
	}
	
	private String getParentItemId(Cursor groupCursor) {
		int columnIndex = groupCursor.getColumnIndex(MediaColumns._ID);
//		switch (groupBy) {
//		case Friend:
//			columnIndex = groupCursor.getColumnIndex(MediaColumns._ID);
//			break;
//			
//		case Author:
//			columnIndex = groupCursor.getColumnIndex(MediaColumns.AUTHOR_ID);
//			break;
//			
//		default:
//			break;
//		}
		
		return String.valueOf(groupCursor.getLong(columnIndex));
	}
	
	public void closeCursor() {
		Log.d(TAG, "Closing group cursor");
		if(groupCursor != null && !groupCursor.isClosed())
			groupCursor.close();
		
		Log.d(TAG, "Closin children cursors: " + childrenCursors.size());
		for(Map.Entry<String, Cursor> entry: childrenCursors.entrySet()) {
			Cursor c = entry.getValue();
			if(!c.isClosed())
				c.close();
		}
		childrenCursors.clear();
	}

	@Override
	public void registerDataSetObserver(DataSetObserver observer) {
		adapter.registerDataSetObserver(observer);
	}

	@Override
	public void unregisterDataSetObserver(DataSetObserver observer) {
		adapter.unregisterDataSetObserver(observer);
	}

	@Override
	public int getGroupCount() {
		return adapter.getGroupCount();
	}

	@Override
	public int getChildrenCount(int groupPosition) {
		return adapter.getChildrenCount(groupPosition);
	}

	@Override
	public Object getGroup(int groupPosition) {
		return adapter.getGroup(groupPosition);
	}

	@Override
	public Object getChild(int groupPosition, int childPosition) {
		return adapter.getChild(groupPosition, childPosition);
	}

	@Override
	public long getGroupId(int groupPosition) {
		return adapter.getGroupId(groupPosition);
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return adapter.getChildId(groupPosition, childPosition);
	}

	@Override
	public boolean hasStableIds() {
		return adapter.hasStableIds();
	}

	@Override
	public View getGroupView(int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		return adapter.getGroupView(groupPosition, isExpanded, convertView, parent);
	}

	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		return adapter.getChildView(groupPosition, childPosition, isLastChild, convertView, parent);
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return adapter.isChildSelectable(groupPosition, childPosition);
	}

	@Override
	public boolean areAllItemsEnabled() {
		return adapter.areAllItemsEnabled();
	}

	@Override
	public boolean isEmpty() {
		return adapter.isEmpty();
	}

	@Override
	public void onGroupExpanded(int groupPosition) {
		adapter.onGroupExpanded(groupPosition);
	}

	@Override
	public void onGroupCollapsed(int groupPosition) {
		adapter.onGroupExpanded(groupPosition);
	}

	@Override
	public long getCombinedChildId(long groupId, long childId) {
		return adapter.getCombinedChildId(groupId, childId);
	}

	@Override
	public long getCombinedGroupId(long groupId) {
		return adapter.getCombinedGroupId(groupId);
	}

	public ArrayList<Long> getSelectedItemIds() {
		return new ArrayList<Long>(selectedIds);
	}

}
